package ch.idsia.scenarios;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

import ch.idsia.ai.agents.Agent;
import ch.idsia.ai.agents.human.HumanKeyboardAgent;
import ch.idsia.tools.CmdLineOptions;
import ch.idsia.tools.EvaluationInfo;
import ch.idsia.tools.EvaluationOptions;
import ch.idsia.tools.Evaluator;

import competition.cig.cs478.CS478_AStar_Backprop_Learner;
import competition.cig.cs478.CS478_BackpropAgent;
import competition.cig.cs478.backprop.Network;
import competition.cig.cs478.backprop.NetworkAdapter;

public class BackpropLearnerRun {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		EvaluationOptions options = new CmdLineOptions(new String[0]);
        options.setMaxFPS(true);
        options.setVisualization(false);
        options.setNumberOfTrials(1);
        options.setMatlabFileName("");
        options.setLevelDifficulty(1);
        
        
		String filename = "network.ser";
		Network network = null;
		try {
			network = loadNetworkFromFile(filename);
		}
		catch(FileNotFoundException e) {
			NetworkAdapter adapter = new NetworkAdapter();
			network = new Network(adapter.getInputCount(), adapter.getInputCount() * 2, 1, adapter.getOutputCount());
		}
		catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		boolean reloadNetwork = true;
		int iterations = 100;
		
		while (iterations-- > 0) {
			if (reloadNetwork) {
				try {
					network = loadNetworkFromFile(filename);
					reloadNetwork = false;
				}
				catch(FileNotFoundException e) {
					NetworkAdapter adapter = new NetworkAdapter();
					network = new Network(adapter.getInputCount(), adapter.getInputCount() * 2, 1, adapter.getOutputCount());
				}
				catch(Exception e) {
					e.printStackTrace();
				}
			}
	        Agent controller = new CS478_AStar_Backprop_Learner(network);
//	        controller = new HumanKeyboardAgent();
	        options.setAgent(controller);
	        options.setLevelRandSeed((int) (Math.random () * Integer.MAX_VALUE));
	        Evaluator evaluator = new Evaluator (options);
            EvaluationInfo result = evaluator.evaluate().get(0);
	        if(result.marioStatus == 1) {
	        	System.out.println("Saving result from iteration " + iterations);
	        	try{
	        		saveNetworkToFile(network, filename);
	        	}
	        	catch (Exception e) {
	        		e.printStackTrace();
	        	}
	        } else {
	        	System.out.println("Disregarding result from iteration " + iterations);
	        	reloadNetwork = true;
	        }
		}
		
        Agent controller = new CS478_BackpropAgent(network);
//        controller = new HumanKeyboardAgent();
        options.setAgent(controller);
        options.setMaxFPS(false);
        options.setVisualization(true);        
        Evaluator evaluator = new Evaluator (options);
        EvaluationInfo result = evaluator.evaluate().get(0);
	}
	
	private static Network loadNetworkFromFile(String filename) throws Exception {
		FileInputStream fis = new FileInputStream(filename);
		ObjectInputStream ois = new ObjectInputStream(fis);
		Network n = (Network)ois.readObject();
		ois.close();
		return n;
	}
	
	private static void saveNetworkToFile(Network network, String filename) throws Exception {
		FileOutputStream fos = new FileOutputStream(filename);
		ObjectOutputStream oos = new ObjectOutputStream(fos);
		oos.writeObject(network);
		oos.close();
	}
}
